package com.example.weatherforecast.whtrcdn.fragment

import android.os.Bundle
import android.util.Log
import android.widget.TextView
import android.widget.Toast
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.android.volley.Request
import com.android.volley.VolleyError
import com.android.volley.toolbox.StringRequest
import com.example.weatherforecast.R
import com.example.weatherforecast.net.MyVolleyQueue
import com.example.weatherforecast.whtrcdn.WhtrcdnViewModel
import com.example.weatherforecast.whtrcdn.adapter.WeatherInfoForecastListAdapter
import com.example.weatherforecast.whtrcdn.adapter.WeatherInfoIndexListAdapter
import com.example.weatherforecast.whtrcdn.constant.WhtrcdnConstant
import com.example.weatherforecast.whtrcdn.entity.WeatherForecastInfo
import com.example.weatherforecast.whtrcdn.net.WhtrcdnData
import com.fasterxml.jackson.databind.ObjectMapper
import java.text.SimpleDateFormat
import java.util.*
import java.util.regex.Pattern
import kotlin.collections.ArrayList

class WeatherInfoFragment(contentLayoutId: Int, val cityId: String) : BaseFragment(contentLayoutId) {

    private val TAG = WeatherInfoFragment::class.simpleName
    private var weatherIndexRecyclerView: RecyclerView ?= null
    private var weatherForecastRecyclerView: RecyclerView ?= null
    private var viewModel: WhtrcdnViewModel ?= null

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        viewModel = ViewModelProvider(requireActivity(), ViewModelProvider.AndroidViewModelFactory(requireActivity().application)).get(WhtrcdnViewModel::class.java)

        weatherIndexRecyclerView = requireView().findViewById(R.id.rv_weather_index)
        weatherIndexRecyclerView?.layoutManager = GridLayoutManager(requireContext(), 3, GridLayoutManager.VERTICAL, false)
        weatherIndexRecyclerView?.addItemDecoration(DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL))


        weatherForecastRecyclerView = requireView().findViewById(R.id.rv_weather_forecast)
        weatherForecastRecyclerView?.layoutManager = GridLayoutManager(requireContext(), 1, GridLayoutManager.VERTICAL, false)
        weatherForecastRecyclerView?.addItemDecoration(DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL))

        // 请求天气数据
        requestData()
    }

    private fun requestData(){
        // 请求天气数据
        Log.i(TAG, "onActivityCreated: $cityId")
        val weatherRequestUrl = WhtrcdnConstant.WEATHER_INFO_REQUEST_URL + cityId
        Log.i(TAG, "onActivityCreated: $weatherRequestUrl")
        val weatherIndexRequestUrl = WhtrcdnConstant.WEATHER_INFO_INDEX_REQUEST_URL + cityId

        MyVolleyQueue.getMyVolleyQueueInstance(requireContext().applicationContext)?.addRequest(StringRequest(Request.Method.GET, weatherRequestUrl, this, this))
        MyVolleyQueue.getMyVolleyQueueInstance(requireContext().applicationContext)?.addRequest(StringRequest(Request.Method.GET, weatherIndexRequestUrl,
            { response ->
                val data = String(response.toByteArray(Charsets.ISO_8859_1), Charsets.UTF_8)
                viewModel?.parseXmlData(data).also {
                    weatherIndexRecyclerView?.adapter =
                        it?.let { it1 -> WeatherInfoIndexListAdapter(requireContext(), it1) }
                }
            },
            {
                Log.i(TAG, "onActivityCreated: $it")
            }))

        Toast.makeText(requireContext(), "请求时间：" + SimpleDateFormat().format(Date()), Toast.LENGTH_SHORT).show()
    }

    override fun onResume() {
        super.onResume()
        requestData()
    }

    override fun onResponse(response: String?) {
        super.onResponse(response)
        val data = response?.let { String(it.toByteArray(Charsets.ISO_8859_1), Charsets.UTF_8) }
        Log.i(TAG, "onResponse: $data")
        if (data != null) {
            try{
                ObjectMapper().readValue(data, WhtrcdnData::class.java).also {
                    view?.findViewById<TextView>(R.id.tv_weather_temperature)!!.text = it.data.wendu + " ℃"
                    view?.findViewById<TextView>(R.id.tv_weather_city)!!.text = it.data.city
                    view?.findViewById<TextView>(R.id.tv_weather_type)!!.text = it.data.forecast[0].type
                    view?.findViewById<TextView>(R.id.tv_weather_ganmao)!!.text = "提示：${it.data.ganmao}"

                    view?.findViewById<TextView>(R.id.tv_weather_date)!!.text = it.data.forecast[0].date
                    view?.findViewById<TextView>(R.id.tv_weather_temperature_boundary)!!.text = it.data.forecast[0].low + "~" + it.data.forecast[0].high
                    view?.findViewById<TextView>(R.id.tv_weather_wind_level)!!.text = it.data.forecast[0].fengxiang + " " + matchWindLevel(it.data.forecast[0].fengli)

                    weatherForecastRecyclerView?.adapter = WeatherInfoForecastListAdapter(requireContext(), getForecastInfo(it))
                }
            }catch (e: Exception){
                Toast.makeText(requireContext(), "天气数据解析异常", Toast.LENGTH_SHORT).show()
            }
        }else {
            Log.i(TAG, "onResponse: 数据异常")
        }
    }

    private fun matchWindLevel(str: String): String?{

        val regex = "(<!\\[CDATA\\[)(.*)(]])>"
        val pattern = Pattern.compile(regex)
        val matcher = pattern.matcher(str)

        if (matcher.find()){
            return matcher.group(2)
        }
        return ""
    }

    override fun onErrorResponse(error: VolleyError?) {
        super.onErrorResponse(error)
        Log.i(TAG, "onErrorResponse: $error")
    }

    private fun getForecastInfo(whtrcdnData: WhtrcdnData): List<WeatherForecastInfo> {
        val infoList = ArrayList<WeatherForecastInfo>()
        // infoList.add(WeatherForecastInfo.generate(whtrcdnData.data.yesterday))
        whtrcdnData.data.forecast.forEachIndexed{index, forecast ->
            if (index != 0){
                infoList.add(WeatherForecastInfo.generate(forecast))
            }
        }
        return infoList
    }

}